#pragma once
#include <string>
#include <vector>
#include <map>
#include <memory>
#include <thread>
#include <opencv2/opencv.hpp>
extern "C"
{
#include "libavformat/avformat.h"
#include <libavutil/mathematics.h>
#include <libavutil/time.h>
#include <libavutil/samplefmt.h>
#include <libavcodec/avcodec.h>
#include <libavfilter/buffersink.h>
#include <libavfilter/buffersrc.h>
#include "libavutil/avconfig.h"
#include <libavutil/imgutils.h>
#include "libswscale/swscale.h"
};

class Worker {
public:
	Worker(int id, int interval, std::string url);
	~Worker();
	int InitVideo();
	int InitVideo_GPU();
	int InitVideo_FFMpegCPU();
	void ReadFrame();
	void ReadFrame_FFMpegCPU();
	void GetFrameImage_OpencvGPU();
	void GetFrameImage_FFMpegCPU();
	void Run();
	void Run_OneFrame(int index);
	void Stop();
	bool IsStop(){return m_status == 2;}		// 判断是否处于退出状态(包括重连不上的情况!!)
private:
	int m_id;				// Id --- 同时也是 摄像机的唯一Id 可用于反向检索 
	int m_interval;			// 间隔时间
	std::string m_url;		// 源地址

	int m_status = 0;		// 状态
	std::thread m_thread;	// 截帧线程 

	int m_fps = 1;					// 视频帧率
	int m_fps_interval = 0;			// 视频获取的 fps 的毫秒间隔
	
	// OPENCV CPU 处理相关变量 ============================================================================
	cv::VideoCapture m_video_capture;	// CPU版本
	cv::Mat m_frame_cpu;				// CPU版Mat
	
	// GPU 处理相关变量 ============================================================================
	cv::Ptr<cv::cudacodec::VideoReader> m_video_capture_gpu;	// GPU版本
	cv::cuda::GpuMat m_frame_gpu;		// GPU版Mat

	// FFMpeg 处理相关变量 =========================================================================
	AVFormatContext *m_ifmt_ctx = NULL;
    AVPacket m_pkt;
    AVFrame *m_pframe = NULL;
    int m_videoindex = -1;
    AVCodecContext  *m_pCodecCtx;
    AVCodec         *m_pCodec;
    AVCodecParameters *m_codecpar = NULL;
	AVDictionary* m_options = NULL;
	SwsContext* m_conversion = NULL;

	cv::Mat m_frame;					// cv mat	输出

	bool m_lock = false;			// 锁

	int m_index = 0;				// 图片序列号
};